<template>
  <div v-show="data.active" class="remote-root" @mouseenter="mouseenter" @mouseleave="onmouseleave">
    <div class="display">
      <div class="menu">
        <el-button v-show="this.data.isprober === 'YES'" size="mini" @click="onDocument" title="文件列表" icon="el-icon-document-copy" circle></el-button>
        <el-button size="mini" @click="onMenu('min',data)" title="最小化" type="warning" icon="el-icon-minus" circle></el-button>
        <el-button size="mini" @click="onClose" title="关闭" type="danger" icon="el-icon-close" circle></el-button>
        <el-button size="mini" @click="onTest" title="test" type="danger" icon="el-icon-close" circle></el-button>
      </div>
      <div style="text-align:center;padding-top:150px;color:#606266;" v-show="state === 1 || state === 2">
        <h3><i class="el-icon-loading"></i>&nbsp;正在连接中,请稍等</h3>
      </div>
      <div v-show="state === -1" style="text-align:center;padding-top:150px;color:red;">
        <h3><i class="el-icon-warning-outline"></i>&nbsp;连接超时，请检测网络是否正常</h3>
      </div>
      <div v-show="state === 4 || state === 5" style="text-align:center;padding-top:150px;color:red;">
        <h3 v-show="isoked"><i class="el-icon-warning-outline"></i>&nbsp;已断开连接</h3>
        <div v-show="!isoked">
          <h3><i class="el-icon-warning-outline"></i>&nbsp;连接失败，可能原因有已下：</h3>
          <div>网络不正常，请核对相关域名、IP地址是否正常</div>
          <div>如果有登录账号和密码，请核对登录账号、密码是否正确</div>
        </div>
      </div>
      <div ref="viewRef" v-show="state === 3" :id="data.uuid" class="view"></div>
      <RemoteUploadFile :uuid="data.uuid" ref="remoteUploadFile"></RemoteUploadFile>
      <el-drawer :append-to-body="true" title="文件列表" :visible.sync="fileDrawer" direction="rtl">
        <RemoteFile :onDelfileP="onDelfileP" v-for="item in files" :uuid="data.uuid" :data="item" :key="item.fileId"></RemoteFile>
        <div v-show="files.length === 0" style="text-align:center;">
          <h3>无文件</h3>
        </div>
      </el-drawer>
    </div>
  </div>
</template>

<script>
import RemoteUploadFile from "./RemoteUploadFile.vue";
import RemoteFile from "./RemoteFile.vue";

export default {
  name: "Remote",
  props: ["data", "onMenu", "onCloseForParent"],
  components: {
    RemoteUploadFile,
    RemoteFile,
  },
  data() {
    return {
      minScale: 1,
      maxScale: 1,
      scale: 0,
      files: [],
      fileDrawer: false,
      active: true,
      activeGetFile: true,
      guac: null,
      state: null,
      setTimeoutId: null,
      isoked: false,
      isdestroyed: false,
    };
  },
  methods: {
    onTest() {
      this.guac.sendSize(2000, 2000);
      //this.guac.getDisplay().resize(this.guac.getDisplay().getElement(), 666, 666)
      //console.log(this.guac, this.guac.getDisplay());
    },
    connectionComplate() {
      this.updateDisplay();
    },
    updateDisplay() {
      if (!this.isoked) {
        return;
      }
      if (!this.guac.getDisplay().getWidth() || this.guac.getDisplay().getWidth() === 0) {
        setTimeout(() => {
          this.updateDisplay();
        }, 500);
        return;
      }

      this.scale = Math.min(document.body.clientWidth / Math.max(this.guac.getDisplay().getWidth(), 1), document.body.clientHeight / Math.max(this.guac.getDisplay().getHeight(), 1));
      this.maxScale = Math.max(this.scale, 3);
      if (this.guac.getDisplay().getScale() > this.maxScale) {
        this.scale = this.maxScale;
      }
      this.guac.getDisplay().scale(this.scale);
    },
    onDelfileP(fileId) {
      for (let i = 0; i < this.files.length; i++) {
        const tempitem = this.files[i];
        if (tempitem.fileId === fileId) {
          this.files.splice(i, 1);
          break;
        }
      }
    },
    onDocument() {
      this.fileDrawer = true;
    },
    mouseenter() {
      this.active = true;
    },
    onmouseleave() {
      this.active = false;
    },
    onClose() {
      this.data.active = false;
      this.guac.disconnect();
      this.onCloseForParent(this.data);
    },
    onstatechange(state) {
      this.state = state;
      if (state === 1 || state === 2) {
        return;
      }

      if (state === 3) {
        this.isoked = true;
        this.connectionComplate();
      }
      clearTimeout(this.setTimeoutId);
    },
    getFiles() {
      console.log("getFiles", this.activeGetFile, this.data.isprober);
      if (!this.activeGetFile || this.data.isprober === "NO") {
        return;
      }
      this.utils.http(
        "get",
        "/webapi/file/list/get?uuid=" + this.data.uuid,
        {},
        (resp) => {
          this.files = resp;
        }
      );

      setTimeout(() => {
        if (this.isdestroyed) {
          return;
        }
        this.getFiles();
      }, 3000);
    },
    init() {
      const display = document.getElementById(this.data.uuid);
      const tunnel = new window.Guacamole.ChainedTunnel(
        new window.Guacamole.WebSocketTunnel("/websocket-tunnel")
      );
      this.guac = new window.Guacamole.Client(tunnel);
      display.appendChild(this.guac.getDisplay().getElement());
      this.guac.onstatechange = this.onstatechange;
      this.guac.connect(`uuid=${this.data.uuid}&width=${document.body.clientWidth}&height=${document.body.clientHeight}`);

      this.setTimeoutId = setTimeout(() => {
        this.state = -1;
      }, parseInt(this.config.user.last_date_max_sec) * 1000);

      window.onunload = () => {
        this.guac.disconnect();
      };

      var mouse = new window.Guacamole.Mouse(this.guac.getDisplay().getElement());
      mouse.onmousedown = mouse.onmouseup = mouse.onmousemove = (mouseState) => {
        var scaledState = new window.Guacamole.Mouse.State(
          mouseState.x / this.guac.getDisplay().getScale(),
          mouseState.y / this.guac.getDisplay().getScale(),
          mouseState.left,
          mouseState.middle,
          mouseState.right,
          mouseState.up,
          mouseState.down);
        this.guac.sendMouseState(scaledState);
      };

      var keyboard = new window.Guacamole.Keyboard(document);

      keyboard.onkeydown = (keysym) => {
        if (!this.active) {
          return true;
        }
        this.guac.sendKeyEvent(1, keysym);
      };

      keyboard.onkeyup = (keysym) => {
        if (!this.active) {
          return true;
        }
        this.guac.sendKeyEvent(0, keysym);
      };

      display.addEventListener(
        "dragenter",
        (e) => {
          e.stopPropagation();
          e.preventDefault();
        },
        false
      );

      display.addEventListener(
        "dragover",
        (e) => {
          e.stopPropagation();
          e.preventDefault();
        },
        false
      );

      display.addEventListener(
        "drop",
        (e) => {
          e.stopPropagation();
          e.preventDefault();
          var dt = e.dataTransfer;
          var files = dt.files;
          var file = files[0];

          if (this.data.isprober === "NO") {
            this.$notify({
              title: "发送文件",
              message: "被控方未安装[百百堡垒机]客户端，无法发送文件",
              type: "error",
            });
            return;
          }

          this.$refs.remoteUploadFile.upload(file);
        },
        false
      );

      this.utils.on(this._uid, "refresh_client_wh", () => {
        this.updateDisplay();
      });

      this.getFiles();
    },
  },
  mounted() {
    this.init();
  },
  destroyed() {
    this.isdestroyed = true;
    this.active = false;
    this.activeGetFile = false;
    clearTimeout(this.setTimeoutId);
    this.utils.unon(this._uid, "refresh_client_wh");
  },
};
</script>

<style>
.remote-root {
  top: 0px;
  position: absolute;
  background-color: #ffffff;
  z-index: 3;
  height: 100%;
  width: 100%;
  overflow: hidden;
}

.remote-root .minbtn {
  position: absolute;
  cursor: pointer;
  bottom: 10px;
  right: 10px;
}

.remote-root .display {
  position: absolute;
  height: 100%;
  width: 100%;
}

.remote-root .display .menu {
  position: absolute;
  z-index: 10;
  text-align: center;
  right: 200px;
  top: 10px;
  opacity: 0.3;
}

.remote-root .display .menu:hover {
  opacity: 1;
}
</style>